<script setup>
import 'leaflet/dist/leaflet.css'
import '@supermap/iclient-leaflet/css/index'

import iServerConfigUrl from '/iServerConfig.json?url'

import { Edit, Position, Plus, Delete, Location, Top, Bottom, Back, Right } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import $ from 'jquery'
import axios from 'axios'

import L from 'leaflet'
import '@supermap/iclient-leaflet'
import 'proj4leaflet'
import { antPath } from "leaflet-ant-path";

import { inject } from 'vue'
</script>

<template>
    <el-button :icon="Edit" circle class="findPathEditBtn" @click="findPathEditCardStatus" />
    <el-card class="findPathCard">
        <template #header>
            <div class="findPathCardHeader">
                <span>最佳路径</span>
            </div>
        </template>
        <el-table class="guideInfoTable" :data="guideInfosData">
            <el-table-column label="行驶导引" align="left" show-overflow-tooltip>
                <template #default="scope">
                    <span>
                        <el-button :icon="scope.row.icon" circle text></el-button>
                        {{ scope.row.description }}
                    </span>
                </template>
            </el-table-column>
        </el-table>
        <el-button class="button" :icon="Plus" round :disabled="addNodeBtnDisabled" @click="handleAddNodeBtnClicked"></el-button>
        <el-button class="button" :icon="Delete" round :disabled="clearNodesBtnDisabled" @click="handleClearNodesBtnClicked"></el-button>
        <el-button class="button" :icon="Position" round :disabled="findPathBtnDisabled" @click="handleFindPathBtnClicked">查询</el-button>
        <el-checkbox class="isSSCAnalystMode" v-model="isSSCAnalystMode" label="是否使用 SSC 分析模型"></el-checkbox>
    </el-card>
</template>

<script>
export default {
    name: 'BestPathAnalyst',
    data() {
        return {
            restMapUrl: undefined,
            networkAnalystUrl: undefined,
            networkAnalystWithoutSSCUrl: undefined,
            addNodeBtnDisabled: false,
            clearNodesBtnDisabled: true,
            findPathBtnDisabled: true,
            map: undefined,
            clickedPoints: [],
            findPathResultLayers: [],
            guideInfosData: [],
            isSSCAnalystMode: true
        }
    },
    mounted() {
        this.map = inject('map');

        axios.get(iServerConfigUrl).then(res => {
            var iServerConfig = res.data;
            this.restMapUrl = `${iServerConfig.urls.BestPathAnalyst.protocol}://${iServerConfig.urls.BestPathAnalyst.hostname}:${iServerConfig.urls.BestPathAnalyst.port}/${iServerConfig.urls.BestPathAnalyst.restMapUrl}`;
            this.networkAnalystUrl = `${iServerConfig.urls.BestPathAnalyst.protocol}://${iServerConfig.urls.BestPathAnalyst.hostname}:${iServerConfig.urls.BestPathAnalyst.port}/${iServerConfig.urls.BestPathAnalyst.networkAnalystUrl}`;
            this.networkAnalystWithoutSSCUrl = `${iServerConfig.urls.BestPathAnalyst.protocol}://${iServerConfig.urls.BestPathAnalyst.hostname}:${iServerConfig.urls.BestPathAnalyst.port}/${iServerConfig.urls.BestPathAnalyst.networkAnalystWithoutSSCUrl}`;

            // 还原 map 显示范围
            if (this.map._size.x !== document.body.clientWidth) {
                $("#map")[0].style.width = '';
                this.map._size.x = document.body.clientWidth;
            }

            this.map.options.crs = new L.supermap.CRS.NonEarthCRS({
                bounds: L.bounds([48.4, -7668.25], [8958.85, -55.58]),
                origin: L.point(48.4, -55.58)
            });
            this.map.flyTo([-3600, 5000], 4);

            // 添加底图
            new L.supermap.tiledMapLayer(this.restMapUrl).addTo(this.map);
        }).catch(err => {
            ElMessage.error(err.stack)
        });
    },
    methods: {
        // 更新最佳路径分析参数面板状态
        findPathEditCardStatus() {
            var findPathStyleCard = $(".findPathCard")[0];
            if (findPathStyleCard.style.display !== 'none') {
                findPathStyleCard.style.display = 'none';
            } else {
                findPathStyleCard.style.display = 'block';
            }
        },

        // 新增点
        handleAddNodeBtnClicked() {
            this.map.on('click', e => {
                var marker = new L.marker([e.latlng.lat, e.latlng.lng]);
                marker.addTo(this.map);
                this.clickedPoints[this.clickedPoints.length] = marker;

                if (this.clickedPoints.length > 0) {
                    this.clearNodesBtnDisabled = false;
                }

                if (this.clickedPoints.length > 1) {
                    this.findPathBtnDisabled = false;
                }
            });

            this.addNodeBtnDisabled = true;
        },

        // 清空选点
        handleClearNodesBtnClicked() {
            this.map.off('click');
            this.addNodeBtnDisabled = false;
            this.clearNodesBtnDisabled = true;
            this.findPathBtnDisabled = true;

            if (this.findPathResultLayers.length > 0) {
                for (let i = 0; i < this.findPathResultLayers.length; i++) {
                    const findPathLayer = this.findPathResultLayers[i];
                    findPathLayer.remove();
                }
                this.findPathResultLayers = [];
            }

            if (this.clickedPoints.length > 0) {
                for (let i = 0; i < this.clickedPoints.length; i++) {
                    const clickedPoint = this.clickedPoints[i];
                    clickedPoint.remove();
                }
                this.clickedPoints = [];
            }

            if (this.guideInfosData.length > 0) {
                this.guideInfosData = [];
            }
        },

        // 最佳路径查询按钮点击
        handleFindPathBtnClicked() {
            if (this.findPathResultLayers.length > 0) {
                this.guideInfosData = [];

                for (let i = 0; i < this.findPathResultLayers.length; i++) {
                    const findPathLayer = this.findPathResultLayers[i];
                    findPathLayer.remove();
                }
                this.findPathResultLayers = [];
            }

            if (this.clickedPoints.length > 1) {
                this.clickedPoints[0].bindTooltip('起点');
                this.clickedPoints[this.clickedPoints.length - 1].bindTooltip('终点');
                for (let i = 1; i < this.clickedPoints.length - 1; i++) {
                    this.clickedPoints[i].bindTooltip(`途径点 ${i}`);
                }

                var resultSetting = new L.supermap.TransportationAnalystResultSetting({
                    returnEdgeFeatures: true,
                    returnEdgeGeometry: true,
                    returnEdgeIDs: true,
                    returnNodeFeatures: true,
                    returnNodeGeometry: true,
                    returnNodeIDs: true,
                    returnPathGuides: true,
                    returnRoutes: true
                });

                var analystParameter = new L.supermap.TransportationAnalystParameter({
                    resultSetting: resultSetting,
                    weightFieldName: "SmLength"
                });

                var nodes = this.clickedPoints.map(marker => {
                    return new L.point(marker._latlng.lng, marker._latlng.lat);
                });

                var findPathParameter = new L.supermap.FindPathParameters({
                    isAnalyzeById: false,
                    nodes: nodes,
                    parameter: analystParameter
                });

                var that = this;
                var findPathService = new L.supermap.NetworkAnalystService(this.isSSCAnalystMode ? this.networkAnalystUrl : this.networkAnalystWithoutSSCUrl);
                findPathService.findPath(findPathParameter, function (serviceResult) {
                    var result = serviceResult.result;
                    result.pathList.map(function (result) {
                        that.findPathResultLayers[that.findPathResultLayers.length] = antPath(new L.geoJSON(result.route).getLayers()[0]._latlngs, {
                            delay: 500,
                            dashArray: [15, 15],
                            weight: 6,
                            color: "#26A000",
                            pulseColor: "#FFFFFF",
                            paused: false,
                            reverse: false,
                            hardwareAccelerated: true,
                        }).addTo(that.map);

                        if (result.pathGuideItems !== null) {
                            var guideItems = result.pathGuideItems.features;
                            if (guideItems !== null && guideItems.length > 0) {
                                for (let i = 0; i < guideItems.length; i += 2) {
                                    const guideItem = guideItems[i];
                                    var icon = undefined;
                                    var turnType = guideItem.properties.turnType;
                                    switch (turnType) {
                                        case 'AHEAD':
                                            icon = Top;
                                            break;
                                        case 'BACK':
                                            icon = Bottom;
                                            break;
                                        case 'LEFT':
                                            icon = Back;
                                            break;
                                        case 'RIGHT':
                                            icon = Right;
                                            break;
                                        default:
                                            icon = Location;
                                            break;
                                    }

                                    if (i === 0 || i === guideItems.length - 1) {
                                        icon = Location;
                                    }

                                    var description = i === guideItems.length - 1 ? guideItem.properties.description : `${guideItem.properties.description}，${guideItems[i + 1].properties.description}`;

                                    that.guideInfosData[that.guideInfosData.length] = {
                                        icon: icon,
                                        description: description
                                    };
                                }
                            }
                        } else {
                            ElMessage.warning('分析结果暂时行驶导引信息，若需要该信息，请切换分析模式');
                        }
                    });
                });
            }
        }
    }
}
</script>

<style scoped>
.findPathEditBtn {
    top: 90px;
    right: 30px;
    z-index: 1000;
    position: absolute;
    background-color: rgba(240, 255, 255, 0.7);
}

.findPathCard {
    position: absolute;
    width: 360px;
    height: 560px;
    z-index: 999;
    background-color: rgba(240, 255, 255, 0.7);
    right: 0px;
    margin: 20px;
    border-radius: 20px;
    line-height: 866px;
}

.findPathCardHeader {
    line-height: 32px;
    font-weight: 600;
    font-size: 24px;
}

.guideInfoTable {
    overflow: auto;
    position: absolute;
    width: calc(100% - 40px);
    line-height: 32px;
    max-height: 376px;
    height: 376px;
}

.button {
    font-size: 16px;
    font-weight: 600;
}

.isSSCAnalystMode {
    position: absolute;
    font-size: 16px;
    font-weight: 600;
    bottom: 56px;
    left: 20px;
}
</style>